package cn.scw.project.goods.service.impl;

import cn.scw.common.constant.DictTypeConsts;
import cn.scw.common.constant.FacConsts;
import cn.scw.common.constant.GComConsts;
import cn.scw.common.constant.SysConsts;
import cn.scw.common.exception.CustomException;
import cn.scw.common.utils.SecurityUtils;
import cn.scw.common.utils.StringUtils;
import cn.scw.common.utils.UUIDUtils;
import cn.scw.common.utils.bean.ToolUtils;
import cn.scw.common.utils.pay.ConfigUtil;
import cn.scw.common.utils.pay.PayUtils;
import cn.scw.common.utils.security.Md5Utils;
import cn.scw.common.utils.sql.JpaUtil;
import cn.scw.framework.web.domain.AjaxResult;
import cn.scw.project.facility.domain.netework.bean.FacFacilityAutoAddReq;
import cn.scw.project.facility.service.IFacFacilityService;
import cn.scw.project.goods.domain.*;
import cn.scw.project.goods.domain.netework.bean.GCommodityOrderAddReq;
import cn.scw.project.goods.domain.netework.bean.GCommodityOrderListReq;
import cn.scw.project.goods.domain.netework.bean.GCommodityOrderUpdReq;
import cn.scw.project.goods.domain.netework.bean.GOrderCommodityAddReq;
import cn.scw.project.goods.domain.vo.GCommodityOrderVo;
import cn.scw.project.goods.domain.vo.GCouponUserVo;
import cn.scw.project.goods.mapper.GCommodityOrderMapper;
import cn.scw.project.goods.service.*;
import cn.scw.project.system.domain.SysDealer;
import cn.scw.project.system.domain.SysUser;
import cn.scw.project.system.domain.netework.bean.SysUserExpendAddReq;
import cn.scw.project.system.service.ISysDealerService;
import cn.scw.project.system.service.ISysDictDataService;
import cn.scw.project.system.service.ISysUserExpendService;
import cn.scw.project.system.service.ISysUserService;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 商品订单Service业务层处理
 *
 * @author api
 * @date 2020-05-20
 */
@Service
public class GCommodityOrderServiceImpl implements IGCommodityOrderService {
    @Autowired
    private GCommodityOrderMapper gCommodityOrderMapper;
    @Autowired
    private IGOrderCommodityService gOrderCommodityService;
    @Autowired
    private IGCommodityService gCommodityService;
    @Autowired
    private IGAddressService gAddressService;
    @Autowired
    private ISysDictDataService sysDictDataService;
    @Autowired
    private IGCommodityModelService gCommodityModelService;
    @Autowired
    private IGCouponService gCouponService;
    @Autowired
    private IGCouponUserService gCouponUserService;
    @Autowired
    private ISysUserService iSysUserService;
    @Autowired
    private ISysUserExpendService iSysUserExpendService;
    @Autowired
    private IFacFacilityService iFacFacilityService;
    @Autowired
    private ISysDealerService iSysDealerService;

    /**
     * 查询商品订单
     *
     * @param id 商品订单ID
     * @return 商品订单
     */
    @Override
    public GCommodityOrderVo selectGCommodityOrderVoById(Long id) {
        return gCommodityOrderMapper.selectGCommodityOrderVoById(id);
    }

    @Override
    public GCommodityOrder selectGCommodityOrderById(Long id) {
        return gCommodityOrderMapper.selectGCommodityOrderById(id);
    }

    /**
     * 查询商品订单列表
     *
     * @param req 商品订单
     * @return 商品订单
     */
    @Override
    public List<GCommodityOrderVo> selectGCommodityOrderList(GCommodityOrderListReq req) {
        req.setUserName(JpaUtil.getNullOrLikeStr(req.getUserName()));
        return gCommodityOrderMapper.selectGCommodityOrderList(req);
    }

    @Override
    public List<GCommodityOrderVo> selectGCommodityOrderUserList(String statusCode) {
        return gCommodityOrderMapper.selectGCommodityOrderUserList(statusCode);
    }

    /**
     * 新增商品订单
     *
     * @param req 商品订单
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertGCommodityOrder(GCommodityOrderAddReq req) throws JDOMException, IOException {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        GAddress gAddress = gAddressService.selectGAddressById(req.getAddressId());
        if (gAddress == null)
            throw new CustomException("请选择收货地址");
        if (!sysDictDataService.existsDictLabel(DictTypeConsts.SYS_PAY_TYPE, req.getPayType()))
            throw new CustomException("请选择支付方式");
        List<GOrderCommodityAddReq> orderReqList = req.getOrderCommodityList();
        if (orderReqList == null || orderReqList.size() < 1)
            throw new CustomException("请选择商品");
        List<GOrderCommodity> orderCommodityList = new ArrayList<>();
        // 订单金额
        double money = 0;
        List<String> purchasingTypesList = new ArrayList<>();
        for (GOrderCommodityAddReq orderCommodityReq : orderReqList) {
            GCommodity gCommodity = gCommodityService.selectGCommodityById(orderCommodityReq.getCommodityId());
            if (gCommodity == null)
                throw new CustomException("商品不存在");
            if (!gCommodity.getIsPutaway())
                throw new CustomException("商品已下架");


            GOrderCommodity orderCommodity = new GOrderCommodity(orderCommodityReq.getCommodityId(), orderCommodityReq.getCount(), gCommodity.getName(), gCommodity.getLitimgUrl());
            if (gCommodity.getIsModel()) {
                if (orderCommodityReq.getModelId() == null)
                    throw new CustomException("请选择规格");
                GCommodityModel model = gCommodityModelService.selectGCommodityModelById(orderCommodityReq.getModelId());
                if (model == null)
                    throw new CustomException("请选择正确的规格");
                orderCommodity.setModelId(model.getId());
                orderCommodity.setModelName(model.getName());
                money += (model.getPrice() * orderCommodity.getCount() + gCommodity.getCashPledge());
                // 增加押金消费记录
                SysUserExpendAddReq expendReq = new SysUserExpendAddReq(SysConsts.EXPEND_TYPE_CASH_PLEDGE, gCommodity.getId(), gCommodity.getCashPledge());
                iSysUserExpendService.insertSysUserExpend(expendReq);
            } else {
                money += (gCommodity.getPrice() * orderCommodity.getCount() + gCommodity.getCashPledge());
            }
            if (gCommodity.getCount() < 1)
                throw new CustomException("商品数量不足");
            // 购买商品后自动添加到设备-未实现

            // 购买租赁设备后增加押金消费记录
            if (gCommodity.getPurchasingTypes().equals(GComConsts.purchasing_types_rent)) {
                SysUserExpendAddReq expendAddReq = new SysUserExpendAddReq(SysConsts.EXPEND_TYPE_RELET, gCommodity.getId(), money);
                iSysUserExpendService.insertSysUserExpend(expendAddReq);
                // 包月租赁时商品数量减一
                gCommodity.setCount(gCommodity.getCount() - 1);
                // 调用修改用户是否租用两年
                iSysUserService.updateUserIsRentYear();

                SysDealer dealer = iSysDealerService.selectSysDealerByUserId(user.getUserId());
                FacFacilityAutoAddReq facFacilityAddReq = new FacFacilityAutoAddReq(gCommodity.getName(), dealer.getId(), gCommodity.getId(), gCommodity.getPurchasingTypes(), orderCommodityReq.getCount());
                iFacFacilityService.autoInsertFacFacility(facFacilityAddReq);
            } else {
                if (orderCommodityReq.getCount() > gCommodity.getCount())
                    throw new CustomException("商品数量不足");
                // 非包月购买时商品数量减去购买数量
                gCommodity.setCount(gCommodity.getCount() - orderCommodityReq.getCount());
            }
            gCommodityService.updateGCommodity(gCommodity);

            orderCommodityList.add(orderCommodity);
            // 计算商品类型对应的优惠券类型
            if (gCommodity.getFacilityType().equals("1"))
                purchasingTypesList.add("3");
            else {
                if (gCommodity.getPurchasingTypes().equals("0"))
                    purchasingTypesList.add("1");
                else if (gCommodity.getPurchasingTypes().equals("1") || gCommodity.getPurchasingTypes().equals("2"))
                    purchasingTypesList.add("2");
            }
        }
        String number = UUIDUtils.getOrderNumberByUUId();
        GCommodityOrder order = new GCommodityOrder(number, user.getUserId(), money, "0", false, req.getPayType(), false, req.getAddressId(), req.getBuyerMessage());

        // 实付金额
        if (req.getCouponId() != null) {
            GCouponUserVo gCouponUser = gCouponUserService.selectGCouponUserVoById(req.getCouponId());
            if (gCouponUser == null)
                throw new CustomException("优惠券不存在");

            // 验证优惠券是否可用
            gCouponUserService.verify(gCouponUser, purchasingTypesList);

            // 计算实付金额
            double payMoney = money - gCouponUser.getGCoupon().getMoney();
            order.setPayMoney(payMoney);
        } else {
            order.setPayMoney(money);
        }
        AjaxResult result;
        if (order.getPayType().equals(FacConsts.PAY_TYPE_WX)) {
            int i = gCommodityOrderMapper.insertGCommodityOrder(order);
            if (i < 1)
                throw new CustomException("订单添加失败");
            result = PayUtils.pay("商品购买", order.getNumber(), order.getPayMoney(), user.getOpenId(), ConfigUtil.NOTIFY_URL_COMMODITY,false);
        } else {
//            double userMoney = user.getMoney();
//            if (userMoney < order.getPayMoney())
//                throw new CustomException("余额不足");
//            user.setMoney(userMoney - order.getPayMoney());
//            iSysUserService.updateUser(user);
//            order.setIsPay(true);
//            order.setStatusCode(GComConsts.ORDER_STATUS_SEND);
//            order.setPayDate(new Date());

            int i = gCommodityOrderMapper.insertGCommodityOrder(order);
            if (i < 1)
                throw new CustomException("订单添加失败");
            result = AjaxResult.success(order);
        }
        for (GOrderCommodity orderCommodity : orderCommodityList) {
            orderCommodity.setOrderId(order.getId());
            gOrderCommodityService.insertGOrderCommodity(orderCommodity);
        }

        return result;
//        return order;
    }

    @Override
    public int pay(Long id, String payPassword) {
        SysUser user = iSysUserService.getCurrentUser();

        if (StringUtils.isBlank(user.getPayPassword()))
            throw new CustomException("请设置支付密码",501);
        if (!user.getPayPassword().equals(Md5Utils.hash(payPassword)))
            throw new CustomException("支付密码不正确",502);
        GCommodityOrder order = this.selectGCommodityOrderById(id);
        if (user.getMoney() < order.getPayMoney())
            throw new CustomException("余额不足");
        double money = user.getMoney() - order.getPayMoney();
        if (!iSysUserService.updateUserMoney(user.getUserId(), money))
            throw new CustomException("支付失败");
        order.setIsPay(true);
        order.setStatusCode(GComConsts.ORDER_STATUS_SEND);
        order.setPayDate(new Date());
        if (order.getCouponId() != null)
            gCouponUserService.use(gCouponUserService.selectGCouponUserVoById(order.getCouponId()));
       return gCommodityOrderMapper.updateGCommodityOrder(order);
    }

    /**
     * 修改商品订单
     *
     * @param req 商品订单
     * @return 结果
     */
    @Override
    public int updateGCommodityOrder(GCommodityOrderUpdReq req) {
        GCommodityOrder order = this.selectGCommodityOrderById(req.getId());
//        if (req.getIsPay()) {
//            order.setPayDate(new Date());
//            order.setStatusCode(GComConsts.ORDER_STATUS_SEND);
//        }
        if (req.getIsSend()) {
            if (!order.getIsPay())
                throw new CustomException("订单未支付");
            if (StringUtils.isBlank(req.getLogisticsNumber()))
                throw new CustomException("请输入物流号");
            order.setSendDate(new Date());
            order.setStatusCode(GComConsts.ORDER_STATUS_SIGN_IN);
        }
        if (req.getIsSignIn()) {
            if (!order.getIsSend())
                throw new CustomException("订单未发货");
            order.setStatusCode(GComConsts.ORDER_STATUS_FINISH);
        }
        ToolUtils.copyPropertiesIgnoreNull(req, order);

        return gCommodityOrderMapper.updateGCommodityOrder(order);
    }

    @Override
    public int updateGCommodityOrder(GCommodityOrder req) {
        return gCommodityOrderMapper.updateGCommodityOrder(req);
    }

    /**
     * 批量删除商品订单
     *
     * @param ids 需要删除的商品订单ID
     * @return 结果
     */
    @Override
    public int deleteGCommodityOrderByIds(Long[] ids) {
        return gCommodityOrderMapper.deleteGCommodityOrderByIds(ids);
    }

    /**
     * 删除商品订单信息
     *
     * @param id 商品订单ID
     * @return 结果
     */
    @Override
    public int deleteGCommodityOrderById(Long id) {
        return gCommodityOrderMapper.deleteGCommodityOrderById(id);
    }

    @Override
    public GCommodityOrder selectGCommodityOrderByNumber(String number) {
        return gCommodityOrderMapper.selectGCommodityOrderByNumber(number);
    }
}
